<?php
namespace app\index\controller;
use think\Controller;
use think\Db;
class Index extends Controller
{
    // 定义配置项
    private $config=array(
        'APPID'              => 'wxa7b1e', // 微信支付APPID.
        'MCHID'              => '15101', // 微信支付MCHID 商户收款账号  1556016481
        'KEY'                => 'dhgyQZySLV13ESW4', // 微信支付KEY  uniNCx3NaBq8yt7pFh4m1gY1dIqsALAy
        'APPSECRET'          => '7b92d85bdaebd6610c', // 公众帐号secert (公众号支付专用)
        'NOTIFY_URL'         => 'index/Index/huidiao', // 接收支付状态的连接
        'AUTH_URL'         => '/index/Auth2/getuser', // 接收支付状态的连接

    );
    public function index()
    {
        if(isset($_REQUEST['schcodeid']) && $_REQUEST['schcodeid']){
            $id = $_REQUEST['schcodeid'];
        }else{
            echo '不合法二维码';
            exit();
        }
        $data = Db::table('up_offline_schcode')
            ->where('id', $id)
            ->find();
        if(empty($data)){
            echo '此码已不可用';
            exit();
        }
        if($data['status'] != 1){
            echo '此码已暂停收款';
            exit();
        }
        session('schcodeid',$id);
        $this->assign('data',$data);
        if($data['usetype'] == 1){
            $this->assign('type',0);
            return $this->fetch('index/index');
        }
        if(strpos($_SERVER['HTTP_USER_AGENT'],'MicroMessenger')!==false){
            if(!session('?openid22')){
                $authurl = $this->config['AUTH_URL'];
                $appid = config('wechat')['appid'];
                echo "<script> location.href='https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appid}&redirect_uri={$authurl}&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect'; </script>";
                exit;
            }
            $this->assign('type',1);
            return $this->fetch('index/index');
        }elseif (strpos($_SERVER['HTTP_USER_AGENT'],'AlipayClient')!==false){
            $this->assign('type',2);
            return $this->fetch('index/index');
        }else{
            echo "请使用微信扫码或者支付宝扫码！";
            exit();
        }
    }
    public function buy()
    {
        $school = $_POST['school'];
        $grade = $_POST['grade'];
        $class = $_POST['class'];
        $name = $_POST['name'];
        $sex = $_POST['sex'];
        $idcard = $_POST['idcard'];
        $money = $_POST['money'];
        $type = $_POST['type'];
        $order = [
            'orderno' => time() . rand(100000,999999),
            'school' => $school,
            'grade' => $grade,
            'class' => $class,
            'name' => $name,
            'sex' => $sex,
            'idcard' => $idcard,
            'money' => $money,
            'time' => date('Y-m-d H:i:s'),
            'type' => $type
        ];
        $id = $_POST['id'];
        $data = Db::table('up_offline_schcode')
            ->where('id', $id)
            ->find();
        if(empty($data)){
            return 3;
        }
        if($data['status'] != 1){
            return 3;
        }
        //-------------------------------------------------------------------------
        if($data['usetype'] == 3){
            $order['height'] = $_POST['height'];
            $order['weight'] = $_POST['weight'];
            $order['size'] = $_POST['size'];
            $order['sw_j'] = $_POST['sw_j'];
            $order['sw_x'] = $_POST['sw_x'];
            $order['sw_y'] = $_POST['sw_y'];
            $order['sw_t'] = $_POST['sw_t'];
            $order['sw_b'] = $_POST['sw_b'];
            $order['sw_k'] = $_POST['sw_k'];
            $order['xiguan'] = $_POST['xiguan'];
            $order['phone'] = $_POST['phone'];
        }
        $order['fromtype'] = $data['usetype'];
        //-------------------------------------------------------------------------
        $res = Db::table('up_offline_order')->insert($order);
        if($res){
            $payorder = array();
            $payorder['body'] = '派逊服饰'; // 描述
            $payorder['total_fee'] = $money*100; // 订单金额
            $payorder['out_trade_no'] = $order['orderno']; // 订单号
            $payorder['product_id'] = ''; // 产品ID
            $payorder['trade_type'] = 'JSAPI'; // 类型
            $respont = $this->WeChatPayReady($payorder);
            if($respont['status'] == 200){
                $json = $this->getOrder($respont['msg']);
                return view('index/pay_done',['json'=>$json]);
            }else{
                return 1;
            }
        }else{
            return 2;
        }

    }
    public function shouji()
    {
        $school = $_POST['school'];
        $grade = $_POST['grade'];
        $class = $_POST['class'];
        $name = $_POST['name'];
        $sex = $_POST['sex'];
        $idcard = $_POST['idcard'];
        $type = $_POST['type'];
        $order = [
            'orderno' => time() . rand(100000,999999),
            'school' => $school,
            'grade' => $grade,
            'class' => $class,
            'name' => $name,
            'sex' => $sex,
            'idcard' => $idcard,
            'time' => date('Y-m-d H:i:s'),
            'type' => $type
        ];
        $id = $_POST['id'];
        $data = Db::table('up_offline_schcode')
            ->where('id', $id)
            ->find();
        if(empty($data)){
            return 3;
        }
        if($data['status'] != 1){
            return 3;
        }
        //-------------------------------------------------------------------------
        $order['height'] = $_POST['height'];
        $order['weight'] = $_POST['weight'];
        $order['size'] = $_POST['size'];
        $order['sw_j'] = $_POST['sw_j'];
        $order['sw_x'] = $_POST['sw_x'];
        $order['sw_y'] = $_POST['sw_y'];
        $order['sw_t'] = $_POST['sw_t'];
        $order['sw_b'] = $_POST['sw_b'];
        $order['sw_k'] = $_POST['sw_k'];
        $order['xiguan'] = $_POST['xiguan'];
        $order['phone'] = $_POST['phone'];
        $order['fromtype'] = $data['usetype'];
        //-------------------------------------------------------------------------
        $res = Db::table('up_offline_order')->insert($order);
        if($res){
            return 1;
        }else{
            return 2;
        }

    }
    /**
     * 统一下单
     * @param  array $order 订单 必须包含支付所需要的参数 body(产品描述)、total_fee(订单喵额)、out_trade_no(订单号)、product_id(产品id)、trade_type(类型：JSAPI，NATIVE，APP)
     */
    public function WeChatPayReady($order,$type=null){
        // 获取配置项
        $weixinpay_config=$this->config;
        $config=array(
            'appid'=>$weixinpay_config['APPID'],
            'mch_id'=>$weixinpay_config['MCHID'],
            'nonce_str'=>'test',
            'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],
            'openid'=>session('openid22'),
            'notify_url'=>$weixinpay_config['NOTIFY_URL']
        );
        if(!empty($type)){
            $config['notify_url']='http://panson.xuanwumobile.com/index/Index/huidiao';
        }
        // 合并配置数据和订单数据
        $data=array_merge($order,$config);

        // 生成签名
        $sign=$this->makeSign($data);
        $data['sign']=$sign;
        $xml=$this->toXml($data);
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';//接收xml数据的文件
        $header[] = "Content-type: text/xml";//定义content-type为xml,注意是数组
        $ch = curl_init ($url);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//严格校验
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        $response = curl_exec($ch);
        if(curl_errno($ch)){
            print curl_error($ch);
        }
        curl_close($ch);
        $result=$this->toArray($response);
        if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
            $res = [
                'status' => 200,
                'msg' => $result['prepay_id']
            ];
        }else{
            $res = [
                'status' => 0,
                'msg' => $result['return_msg']
            ];
        }
        return $res;
    }

    /**
     * 获取时间
     * @return array
     */
    public function getDateBytimeDate($string){
        $replacement = '-';
        $replacement2 = ':';
        $a = substr_replace($string, $replacement, 4, 0);
        $b = substr_replace($a, $replacement, 7, 0);
        $c = substr_replace($b, ' ', 10, 0);
        $d = substr_replace($c, $replacement2, 13, 0);
        $e = substr_replace($d, $replacement2, 16, 0);
        return $e;
    }

    /**
     * 回调
     * @return string
     */
    public function write_admin_log($data)
    {
        $file_name = 'file/log/' . date('Ymd', time()) . '.txt';
        if (is_array($data)) {
            $data_str = implode(' | ', $data);
        } else {
            $data_str = $data;
        }
        file_put_contents($file_name, $data_str . "\r\n\r\n", FILE_APPEND);
    }

    /**
     * 验证
     * @return array 返回数组格式的notify数据
     */
    public function huidiao(){
        // 获取xml
        $xml=file_get_contents('php://input', 'r');
        // 转成php数组
        $getInfo=$this->toArray($xml);
//        $this->write_admin_log($getInfo);
        // 保存原sign
        $data_sign=$getInfo['sign'];
        // sign不参与签名
        unset($getInfo['sign']);
        $sign=$this->makeSign($getInfo);
        // 判断签名是否正确  判断支付状态
        if ($sign===$data_sign && $getInfo['return_code']=='SUCCESS' && $getInfo['result_code']=='SUCCESS') {
            $num = $getInfo['out_trade_no']; // 订单号
            $backno = $getInfo['transaction_id'];//订单号
            Db::table('up_offline_order')->where('orderno',$num)->update([
                'status' => 2,
                'backno' => $backno,
                'time' => date('Y-m-d H:i:s')
            ]);
            $result = true;
        } else{
            $result = false;
        }
        // 返回状态给微信服务器----------------
        if ($result) {
            $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
        }else{
            $str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
        }
        echo $str;
        exit();
    }

    /**
     * 生成签名
     * @return 签名，本函数不覆盖sign成员变量，如要设置签名需要调用SetSign方法赋值
     */
    public function makeSign($data){
        // 去空
        $data=array_filter($data);
        //签名步骤一：按字典序排序参数
        ksort($data);
        $string_a=http_build_query($data);
        $string_a=urldecode($string_a);
        //签名步骤二：在string后加入KEY
        $config=$this->config;
        $string_sign_temp=$string_a."&key=".$config['KEY'];
        //签名步骤三：MD5加密
        $sign = md5($string_sign_temp);
        // 签名步骤四：所有字符转为大写
        $result=strtoupper($sign);
        return $result;
    }

    /**
     * 将xml转为array
     * @param  string $xml xml字符串
     * @return array       转换得到的数组
     */
    public function toArray($xml){
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $result;
    }

    /**
     * 输出xml字符
     * @throws WxPayException
     **/
    public function toXml($data){
        //var_dump($data);
        if(!is_array($data) || count($data) <= 0){
            //throw new WxPayException("数组数据异常！");
        }
        $xml = "<xml>";
        foreach ($data as $key=>$val){
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }

    //数组转xml
    function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
            if (is_numeric($val))
            {
                $xml.="<".$key.">".$val."</".$key.">";

            }
            else
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
        }
        $xml.="</xml>";
        return $xml;
    }

    //post https请求，CURLOPT_POSTFIELDS xml格式
    public function postXmlCurl($xml,$url,$second=30)
    {
        //初始化curl
        $ch = curl_init();
        //超时时间
        curl_setopt($ch,CURLOPT_TIMEOUT,$second);
        //这里设置代理，如果有的话
        //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        if($data)
        {
            curl_close($ch);
            return $data;
        }
        else
        {
            $error = curl_errno($ch);
            echo "curl出错，错误码:$error"."<br>";
            echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
            curl_close($ch);
            return false;
        }
    }

    //获取指定长度的随机字符串
    function getRandChar($length){
        $str = null;
        $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($strPol)-1;

        for($i=0;$i<$length;$i++){
            $str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
        }

        return $str;
    }

    //执行第二次签名，才能返回给客户端使用(微信浏览器H5支付的话有所区别)
    public function getOrder($prepayId){
        $data["appId"] = $this->config["APPID"];
        $data["nonceStr"] = $this->getRandChar(32);
        $data["package"] = "prepay_id=$prepayId";
        $data["signType"] = 'MD5';
        $data["timeStamp"] = strval(time());
        $s = $this->makeSign($data, false);
        $data["paySign"] = $s;
        return json_encode($data);
    }

    /**
     * 获取当前服务器IP
     * @return string
     */
    public  function get_client_ip()
    {
        if ($_SERVER['REMOTE_ADDR']) {
            $cip = $_SERVER['REMOTE_ADDR'];
        } elseif (getenv("REMOTE_ADDR")) {
            $cip = getenv("REMOTE_ADDR");
        } elseif (getenv("HTTP_CLIENT_IP")) {
            $cip = getenv("HTTP_CLIENT_IP");
        } else {
            $cip = "unknown";
        }
        return $cip;
    }
}
